import 'dart:convert';
import 'dart:io';
import 'dart:isolate';

import 'package:flutter_learning/isolate/utils/ly_log.dart';

enum ActionMessageType {
  send("SEND"),
  stop("STOP");

  final String name;
  const ActionMessageType(this.name);
}

class IsolateMessageModel {
  ActionMessageType? type;
  dynamic data;
  String? host;
  int? port;
  IsolateMessageModel({this.data, this.type, this.host, this.port});
  IsolateMessageModel.fromMap(Map map) {
    type = map['type'];
    data = map['data'];
    host = map['host'];
    port = map['port'];
  }
  Map toMap() {
    return {'type': type, 'data': data, 'host': host, 'port': port};
  }
}

class LYIsolateSocketUdpManager {
  late ReceivePort _receivePort;
  Isolate? _isolate;
  SendPort? _sendPort;
  String host = '';
  int port = 0;
  InternetAddress? _internetAddress;

  Future<void> init({required String host, required int port, Function(dynamic)? callBack}) async {
    this.host = host;
    this.port = port;
    _internetAddress = InternetAddress(host);
    _receivePort = ReceivePort();
    // 监听UI消息
    _receivePort.listen((dynamic message) {
      LYLog.d(message);
      if (message is SendPort) {
        _sendPort = message;
      } else {
        callBack?.call(message);
      }
    });

    // 创建新的Isolate并直接传递SendPort
    _isolate = await Isolate.spawn(
      _isolateEntryPoint,
      {"host": host, "port": port, "sendPort": _receivePort.sendPort},
    );
  }

  void sendData({dynamic data, String? host, int? port}) {
    _sendPort?.send(IsolateMessageModel(
            type: ActionMessageType.send,
            data: data,
            host: host ?? this.host,
            port: port ?? this.port)
        .toMap());
  }

  void _stopListening() {
    _sendPort!.send('stop');
    _receivePort.close();
    _isolate?.kill(priority: Isolate.immediate);
  }

  static void _isolateEntryPoint(Map<String, dynamic> parameters) async {
    final mainSendPort = parameters["sendPort"];
    final host = parameters["host"];
    final port = parameters["port"];
    // 创建接收端口
    final ReceivePort isolateReceivePort = ReceivePort();
    // 发送Isolate的SendPort到主UI
    mainSendPort.send(isolateReceivePort.sendPort);
    // 绑定UDP套接字
    final RawDatagramSocket socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, port);
    // 监听Isolate消息（如停止命令或发送消息）
    isolateReceivePort.listen((dynamic map) {
      final messageModel = IsolateMessageModel.fromMap(map);
      switch (messageModel.type) {
        case ActionMessageType.send:
          LYLog.d(messageModel.data);
          final host = messageModel.host;
          final port = messageModel.port;
          LYLog.d(messageModel.host);
          if (host != null && port != null) {
            socket.send(utf8.encode(messageModel.data), InternetAddress(host), port);
          }
          break;
        case ActionMessageType.stop:
          socket.close();
          isolateReceivePort.close();
          break;
        default:
          break;
      }
    });

    // 监听UDP数据包
    socket.listen((RawSocketEvent event) {
      if (event == RawSocketEvent.read) {
        final Datagram? datagram = socket.receive();
        if (datagram != null) {
          final String message = utf8.decode(datagram.data, allowMalformed: true);
          print("======socket.listen===========${message}");
          // 发送消息到主UI
          mainSendPort.send(message);
        }
      }
    });
  }

  static void printCurrentIsolateInfo() {
    final isolate = Isolate.current;
    print('当前 Isolate: ${isolate.debugName ?? '无名'} (${isolate.hashCode})');
  }

  void dispose() {
    _stopListening();
  }
}
